// 14_lifetimes.rs
// 演示 Rust 中的生命周期（lifetimes）

// 1. 生命周期注解语法
// 生命周期参数以 ' 开头，通常使用单个字母表示，如 'a, 'b, 'c
// 生命周期注解不会改变任何引用的实际生命周期长度
// 它们只是告诉编译器多个引用之间的关系

// 2. 函数中的生命周期注解
// 下面的函数返回两个字符串切片中较长的一个
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

// 3. 生命周期省略规则
// 在某些情况下，编译器可以推断生命周期，不需要显式注解
// 规则1: 每个引用参数都有自己的生命周期参数
// 规则2: 如果只有一个输入生命周期参数，它被赋予所有输出生命周期参数
// 规则3: 如果有多个输入生命周期参数，但其中一个是 &self 或 &mut self，
//        self 的生命周期被赋予所有输出生命周期参数

// 以下函数遵循规则1和规则2，不需要显式注解
fn first_word(s: &str) -> &str {
    let bytes = s.as_bytes();
    
    for (i, &item) in bytes.iter().enumerate() {
        if item == b' ' {
            return &s[0..i];
        }
    }
    
    &s[..]
}

// 4. 结构体中的生命周期注解
struct ImportantExcerpt<'a> {
    part: &'a str,
}

// 为结构体实现方法，使用生命周期参数
impl<'a> ImportantExcerpt<'a> {
    fn level(&self) -> i32 {
        3
    }
    
    // 这里使用了规则3，self 的生命周期被赋予返回值
    fn announce_and_return_part(&self, announcement: &str) -> &str {
        println!("Attention please: {}", announcement);
        self.part
    }
}

// 5. 多个生命周期参数
fn longest_with_an_announcement<'a, 'b>(
    x: &'a str,
    y: &'a str,
    ann: &'b str,
) -> &'a str {
    println!("Announcement! {}", ann);
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

// 6. 静态生命周期
// 'static 生命周期表示整个程序的持续时间
// 字符串字面量默认具有 'static 生命周期
fn static_lifetime() {
    let s: &'static str = "I have a static lifetime.";
    println!("静态生命周期字符串: {}", s);
}

// 7. 生命周期与泛型结合
fn generic_with_lifetime<'a, T>(x: &'a str, y: T) -> &'a str 
where 
    T: std::fmt::Display,
{
    println!("y = {}", y);
    x
}

// 8. 复合类型中的生命周期
struct MultiRef<'a, 'b> {
    first: &'a str,
    second: &'b str,
}

// 9. 生命周期与Trait Bound结合
fn lifetime_and_trait<'a, T: std::fmt::Debug + 'a>(x: &'a T) {
    println!("x = {:?}", x);
}

// 10. 生命周期在闭包中的使用
// 闭包可以捕获引用，但通常不需要显式的生命周期注解
fn closure_lifetimes<'a>(x: &'a str) -> impl Fn() -> &'a str + 'a {
    move || x
}

// 11. 深入理解生命周期
// 下面的示例展示了为什么需要生命周期注解
// 考虑这个有问题的函数（不会编译）:
// fn invalid_return(x: &str) -> &str {
//     let y = String::from("local string");
//     &y // 错误：返回了对局部变量的引用
// }

// 12. 生命周期与所有权
// 当需要返回一个引用，但不确定它的生命周期时，
// 通常的解决方案是返回所有权而不是引用
fn returning_ownership(s: &str) -> String {
    String::from(s)
}

// 13. 生命周期的子类型
// 'a: 'b 表示 'a 的生命周期至少与 'b 一样长
struct RefWrapper<'a, 'b: 'a> {
    data: &'a str,
    owner: &'b str,
}

// 14. 省略生命周期注解的方法
impl<'a> ImportantExcerpt<'a> {
    // 这里的生命周期被省略了，但编译器会根据规则推断
    fn get_part(&self) -> &str {
        self.part
    }
}

// 15. 生命周期在实践中的应用
fn find_longest_word<'a>(sentence: &'a str) -> &'a str {
    let mut longest_word = "";
    let mut max_length = 0;
    
    for word in sentence.split_whitespace() {
        if word.len() > max_length {
            max_length = word.len();
            longest_word = word;
        }
    }
    
    longest_word
}

// 将原来的 main 函数改为公共的 run 函数
pub fn run() {
    // 16. 测试 longest 函数
    let string1 = String::from("long string is long");
    {
        let string2 = String::from("xyz");
        let result = longest(string1.as_str(), string2.as_str());
        println!("较长的字符串是: {}", result);
    } // string2 在这里离开作用域
    // string1 仍然有效直到 main 函数结束
    
    // 17. 结构体中的生命周期
    let novel = String::from("Call me Ishmael. Some years ago...");
    let first_sentence = novel.split('.').next().expect("找不到句号");
    let i = ImportantExcerpt {
        part: first_sentence,
    };
    
    println!("摘录的重要部分: {}", i.part);
    println!("摘录的级别: {}", i.level());
    
    let announcement = String::from("注意啦！");
    let returned_part = i.announce_and_return_part(&announcement);
    println!("返回的部分: {}", returned_part);
    
    // 18. 测试 longest_with_an_announcement 函数
    let string3 = String::from("hello");
    let string4 = String::from("world world");
    let ann = String::from("这是一个公告");
    
    let result = longest_with_an_announcement(string3.as_str(), string4.as_str(), &ann);
    println!("较长的字符串是: {}", result);
    
    // 19. 静态生命周期
    static_lifetime();
    
    // 20. 测试泛型与生命周期结合的函数
    let generic_result = generic_with_lifetime("hello", 42);
    println!("泛型与生命周期结合的结果: {}", generic_result);
    
    // 21. 测试复合类型中的生命周期
    let a = String::from("first");
    let b = String::from("second");
    
    let multi = MultiRef {
        first: &a,
        second: &b,
    };
    
    println!("复合引用: first={}, second={}", multi.first, multi.second);
    
    // 22. 测试生命周期与Trait Bound结合的函数
    lifetime_and_trait(&42);
    lifetime_and_trait(&String::from("hello"));
    
    // 23. 测试闭包中的生命周期
    let s = String::from("闭包中的字符串");
    let closure = closure_lifetimes(&s);
    println!("通过闭包访问: {}", closure());
    
    // 24. 测试返回所有权的函数
    let original = String::from("original string");
    let owned_result = returning_ownership(&original);
    println!("返回所有权的结果: {}", owned_result);
    
    // 25. 测试生命周期子类型
    let outer = String::from("outer");
    {
        let inner = String::from("inner");
        let wrapper = RefWrapper {
            data: &inner,
            owner: &outer,
        };
        println!("RefWrapper: data={}, owner={}", wrapper.data, wrapper.owner);
    } // inner 离开作用域，但 outer 仍然有效
    
    // 26. 测试实践中的生命周期应用
    let sentence = String::from("The quick brown fox jumps over the lazy dog");
    let longest_word = find_longest_word(&sentence);
    println!("句子中最长的单词: {}", longest_word);
    
    // 27. 生命周期的重要性
    println!("\n生命周期示例演示完成！");
    println!("生命周期是Rust安全保证的重要组成部分");
    println!("它们确保引用总是有效的，不会出现悬垂引用");
    println!("大多数情况下，编译器可以推断生命周期，但在复杂情况下需要显式注解");
    println!("生命周期注解不会改变引用的实际生命周期，只是告诉编译器引用之间的关系");
}